home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / program / tcpdumpb.zip / libpcap / nametoaddr.c < prev    next >
C/C++ Source or Header  |  1996-07-17  |  8KB  |  373 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * Name to id translation routines used by the scanner.
  22.  * These functions are not time critical.
  23.  */
  24.  
  25. #ifndef lint
  26. static char rcsid[] =
  27.     "@(#) $Header: nametoaddr.c,v 1.43 96/07/17 00:11:41 leres Exp $ (LBL)";
  28. #endif
  29.  
  30. #include <sys/param.h>
  31. #include <sys/types.h>                /* concession to AIX */
  32. #include <sys/socket.h>
  33.  
  34. #if __STDC__
  35. struct mbuf;
  36. struct rtentry;
  37. #endif
  38.  
  39. #include <net/if.h>
  40. #include <netinet/in.h>
  41. #include <netinet/if_ether.h>
  42. #include <arpa/inet.h>
  43.  
  44. #include <ctype.h>
  45. #include <errno.h>
  46. #include <stdlib.h>
  47. #include <memory.h>
  48. #include <netdb.h>
  49. #include <stdio.h>
  50.  
  51. #include "pcap-int.h"
  52.  
  53. #include "gencode.h"
  54. #include <pcap-namedb.h>
  55.  
  56. #include "gnuc.h"
  57. #ifdef HAVE_OS_PROTO_H
  58. #include "os-proto.h"
  59. #endif
  60.  
  61. #ifndef NTOHL
  62. #define NTOHL(x) (x) = ntohl(x)
  63. #define NTOHS(x) (x) = ntohs(x)
  64. #endif
  65.  
  66. static inline int xdtoi(int);
  67.  
  68. /*
  69.  *  Convert host name to internet address.
  70.  *  Return 0 upon failure.
  71.  */
  72. bpf_u_int32 **
  73. pcap_nametoaddr(const char *name)
  74. {
  75. #ifndef h_addr
  76.     static bpf_u_int32 *hlist[2];
  77. #endif
  78.     bpf_u_int32 **p;
  79.     struct hostent *hp;
  80.  
  81.     if ((hp = gethostbyname(name)) != NULL) {
  82. #ifndef h_addr
  83.         hlist[0] = (bpf_u_int32 *)hp->h_addr;
  84.         NTOHL(hp->h_addr);
  85.         return hlist;
  86. #else
  87.         for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
  88.             NTOHL(**p);
  89.         return (bpf_u_int32 **)hp->h_addr_list;
  90. #endif
  91.     }
  92.     else
  93.         return 0;
  94. }
  95.  
  96. /*
  97.  *  Convert net name to internet address.
  98.  *  Return 0 upon failure.
  99.  */
  100. bpf_u_int32
  101. pcap_nametonetaddr(const char *name)
  102. {
  103.     struct netent *np;
  104.  
  105.     if ((np = getnetbyname(name)) != NULL)
  106.         return np->n_net;
  107.     else
  108.         return 0;
  109. }
  110.  
  111. /*
  112.  * Convert a port name to its port and protocol numbers.
  113.  * We assume only TCP or UDP.
  114.  * Return 0 upon failure.
  115.  */
  116. int
  117. pcap_nametoport(const char *name, int *port, int *proto)
  118. {
  119.     struct servent *sp;
  120.     char *other;
  121.  
  122.     sp = getservbyname(name, (char *)0);
  123.     if (sp != NULL) {
  124.         NTOHS(sp->s_port);
  125.         *port = sp->s_port;
  126.         *proto = pcap_nametoproto(sp->s_proto);
  127.         /*
  128.          * We need to check /etc/services for ambiguous entries.
  129.          * If we find the ambiguous entry, and it has the
  130.          * same port number, change the proto to PROTO_UNDEF
  131.          * so both TCP and UDP will be checked.
  132.          */
  133.         if (*proto == IPPROTO_TCP)
  134.             other = "udp";
  135.         else
  136.             other = "tcp";
  137.  
  138.         sp = getservbyname(name, other);
  139.         if (sp != 0) {
  140.             NTOHS(sp->s_port);
  141. #ifdef notdef
  142.             if (*port != sp->s_port)
  143.                 /* Can't handle ambiguous names that refer
  144.                    to different port numbers. */
  145.                 warning("ambiguous port %s in /etc/services",
  146.                     name);
  147. #endif
  148.             *proto = PROTO_UNDEF;
  149.         }
  150.         return 1;
  151.     }
  152. #if defined(ultrix) || defined(__osf__)
  153.     /* Special hack in case NFS isn't in /etc/services */
  154.     if (strcmp(name, "nfs") == 0) {
  155.         *port = 2049;
  156.         *proto = PROTO_UNDEF;
  157.         return 1;
  158.     }
  159. #endif
  160.     return 0;
  161. }
  162.  
  163. int
  164. pcap_nametoproto(const char *str)
  165. {
  166.     struct protoent *p;
  167.  
  168.     p = getprotobyname(str);
  169.     if (p != 0)
  170.         return p->p_proto;
  171.     else
  172.         return PROTO_UNDEF;
  173. }
  174.  
  175. #include "ethertype.h"
  176.  
  177. struct eproto {
  178.     char *s;
  179.     u_short p;
  180. };
  181.  
  182. /* Static data base of ether protocol types. */
  183. struct eproto eproto_db[] = {
  184.     { "pup", ETHERTYPE_PUP },
  185.     { "xns", ETHERTYPE_NS },
  186.     { "ip", ETHERTYPE_IP },
  187.     { "arp", ETHERTYPE_ARP },
  188.     { "rarp", ETHERTYPE_REVARP },
  189.     { "sprite", ETHERTYPE_SPRITE },
  190.     { "mopdl", ETHERTYPE_MOPDL },
  191.     { "moprc", ETHERTYPE_MOPRC },
  192.     { "atalk", ETHERTYPE_ATALK },
  193.     { "decnet", ETHERTYPE_DN },
  194.     { "lat", ETHERTYPE_LAT },
  195.     { "sca", ETHERTYPE_SCA },
  196.     { "lanbridge", ETHERTYPE_LANBRIDGE },
  197.     { "vexp", ETHERTYPE_VEXP },
  198.     { "vprod", ETHERTYPE_VPROD },
  199.     { "atalk", ETHERTYPE_ATALK },
  200.     { "atalkarp", ETHERTYPE_AARP },
  201.     { "loopback", ETHERTYPE_LOOPBACK },
  202.     { "decdts", ETHERTYPE_DECDTS },
  203.     { "decdns", ETHERTYPE_DECDNS },
  204.     { (char *)0, 0 }
  205. };
  206.  
  207. int
  208. pcap_nametoeproto(const char *s)
  209. {
  210.     struct eproto *p = eproto_db;
  211.  
  212.     while (p->s != 0) {
  213.         if (strcmp(p->s, s) == 0)
  214.             return p->p;
  215.         p += 1;
  216.     }
  217.     return PROTO_UNDEF;
  218. }
  219.  
  220. /* Hex digit to integer. */
  221. static inline int
  222. xdtoi(c)
  223.     register int c;
  224. {
  225.     if (isdigit(c))
  226.         return c - '0';
  227.     else if (islower(c))
  228.         return c - 'a' + 10;
  229.     else
  230.         return c - 'A' + 10;
  231. }
  232.  
  233. int
  234. __pcap_atoin(const char *s, bpf_u_int32 *addr)
  235. {
  236.     u_int n;
  237.     int len;
  238.  
  239.     *addr = 0;
  240.     len = 0;
  241.     while (1) {
  242.         n = 0;
  243.         while (*s && *s != '.')
  244.             n = n * 10 + *s++ - '0';
  245.         *addr <<= 8;
  246.         *addr |= n & 0xff;
  247.         len += 8;
  248.         if (*s == '\0')
  249.             return len;
  250.         ++s;
  251.     }
  252.     /* NOTREACHED */
  253. }
  254.  
  255. int
  256. __pcap_atodn(const char *s, bpf_u_int32 *addr)
  257. {
  258. #define AREASHIFT 10
  259. #define AREAMASK 0176000
  260. #define NODEMASK 01777
  261.  
  262.     u_int node, area;
  263.  
  264.     if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
  265.         bpf_error("malformed decnet address '%s'", s);
  266.  
  267.     *addr = (area << AREASHIFT) & AREAMASK;
  268.     *addr |= (node & NODEMASK);
  269.  
  270.     return(32);
  271. }
  272.  
  273. /*
  274.  * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
  275.  * ethernet address.  Assumes 's' is well formed.
  276.  */
  277. u_char *
  278. pcap_ether_aton(const char *s)
  279. {
  280.     register u_char *ep, *e;
  281.     register u_int d;
  282.  
  283.     e = ep = (u_char *)malloc(6);
  284.  
  285.     while (*s) {
  286.         if (*s == ':')
  287.             s += 1;
  288.         d = xdtoi(*s++);
  289.         if (isxdigit(*s)) {
  290.             d <<= 4;
  291.             d |= xdtoi(*s++);
  292.         }
  293.         *ep++ = d;
  294.     }
  295.  
  296.     return (e);
  297. }
  298.  
  299. #ifndef HAVE_ETHER_HOSTTON
  300. /* Roll our own */
  301. u_char *
  302. pcap_ether_hostton(const char *name)
  303. {
  304.     register struct pcap_etherent *ep;
  305.     register u_char *ap;
  306.     static FILE *fp = NULL;
  307.     static init = 0;
  308.  
  309.     if (!init) {
  310.         fp = fopen(PCAP_ETHERS_FILE, "r");
  311.         ++init;
  312.         if (fp == NULL)
  313.             return (NULL);
  314.     } else if (fp == NULL)
  315.         return (NULL);
  316.     else
  317.         rewind(fp);
  318.     
  319.     while ((ep = pcap_next_etherent(fp)) != NULL) {
  320.         if (strcmp(ep->name, name) == 0) {
  321.             ap = (u_char *)malloc(6);
  322.             if (ap != NULL) {
  323.                 memcpy(ap, ep->addr, 6);
  324.                 return (ap);
  325.             }
  326.             break;
  327.         }
  328.     }
  329.     return (NULL);
  330. }
  331. #else
  332.  
  333. #ifndef sgi
  334. extern int ether_hostton(char *, struct ether_addr *);
  335. #endif
  336.  
  337. /* Use the os supplied routines */
  338. u_char *
  339. pcap_ether_hostton(const char *name)
  340. {
  341.     register u_char *ap;
  342.     u_char a[6];
  343.  
  344.     ap = NULL;
  345.     if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
  346.         ap = (u_char *)malloc(6);
  347.         if (ap != NULL)
  348.             memcpy(ap, a, 6);
  349.     }
  350.     return (ap);
  351. }
  352. #endif
  353.  
  354. u_short
  355. __pcap_nametodnaddr(const char *name)
  356. {
  357. #ifdef    DECNETLIB
  358.     struct nodeent *getnodebyname();
  359.     struct nodeent *nep;
  360.     unsigned short res;
  361.  
  362.     nep = getnodebyname(name);
  363.     if (nep == ((struct nodeent *)0))
  364.         bpf_error("unknown decnet host name '%s'\n", name);
  365.  
  366.     memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
  367.     return(res);
  368. #else
  369.     bpf_error("decnet name support not included, '%s' cannot be translated\n",
  370.         name);
  371. #endif
  372. }
  373.